<?php
/**
 * Created by PhpStorm.
 * User: Inhere
 * Date: 2015/2/9
 * Use : ...
 * File: Configurator.php
 */

namespace ulue\web;

use Debug,Ulue,Ioc;

use ulue\libs\datastorage\AbstractDatastorage;
use ulue\core\ioc\Container;
use ulue\libs\helpers\ArrayHelper;
use ulue\core\module\ModuleManager;

class Configurator extends AbstractDatastorage
{
    /**
     * @var Container
     */
    protected $di;

    /**
     * 服务配置数组
     * @var array
     */
    protected $services = [];


    // 可在配置文件设置的 内置服务
    protected $configurableService = [
        'db'         => [
            'target' => 'ulue\base\providers\DatabaseServiceProvider'
        ],
        'dispatcher' => [
            'target' => 'ulue\base\providers\DispatcherServiceProvider'
        ],

        'asset'      => [
            'target' => 'ulue\base\providers\AssetServiceProvider'
        ],
        'cache'      => [
            'target' => 'ulue\base\providers\CacheServiceProvider'
        ],
        'log'        => [
            'target' => 'ulue\base\providers\LoggerServiceProvider'
        ],

        'request'    => [
            'target' => 'ulue\core\request\Request',
            'idAliases' => ['input','app.request']
        ],
        'response'   => [
            'target' => 'ulue\core\response\Response',
            'idAliases' => ['reply','app.response']
        ],

        'session'    => [
            'target' => 'ulue\base\providers\SessionServiceProvider'
        ],
        'language'   => [
            'target' => 'ulue\base\providers\LanguageServiceProvider'
        ],
        'route'      => [
            'target' => 'ulue\base\providers\RouteServiceProvider'
        ],
        'user'       => [
            'target' => 'ulue\base\providers\UserServiceProvider'
        ],

        'view'       => [
            'target' => 'ulue\web\View'
        ],

    ];

    // 内置的不可配置的服务
    protected $insideService = [
        'WebServiceProvider',
    ];

    public function __construct( Container $di=null)
    {
        $this->services = Ulue::loadServiceConfig(APP_ENV);
        $this->di       = $di;
    }

    // 注册服务
    public function registerService()
    {
        $di   = $this->getDi();

        $di->share('cfg', $this);

        //Add app to container
        $di->share('app', [
            'target' => 'ulue\web\Application',
            'params' => [
                Ulue::loadConfiguration(APP_ENV) ,
                $di
            ]
        ])->aliases(['application','system.application','system.app']);

        $services  = ArrayHelper::merge($this->configurableService, $this->services);

        $services['pathMgr']  = [
            'target' => 'ulue\core\utils\PathManager',
            'params' => [
                PROJECT_PATH,
                include SYS_PATH.'/libs/_data/dir_config/project_directory.inc'
            ],
            'idAliases' => ['pathManager'],
            'shared'    => true,
        ];

        $services['urlMgr']  = [
            'target' => 'ulue\core\utils\PathManager',
            'params' => [
                // [
                //     'baseUrl' =>
                // ]
            ],
            'idAliases' => ['urlManager'],
            'shared'    => true,
        ];

        $services['moduleMgr'] = [
            'target' => function($di)
            {
                return new ModuleManager($di->app->modules);
            },
            'idAliases' => ['moduleManager'],
            'shared' => true,
        ];

        // 注册多个服务
        $di->mset($services);

        // Inside 服务注册
        $this->registerInsideService($di);

        // de($di->getServiceNames());

        Debug::trace('服务注册完成。', [
            '已注册服务' => $di->getServiceNames()
            ]);

        return $this;
    }

    /**
     * 注册余下的 没有手动配置的核心服务
     * @param  Container $di
     */
    protected function registerInsideService(Container $di)
    {
        foreach ($this->insideService as $classname) {
            $providerClass = 'ulue\base\providers\\'.$classname;

            $di->registerServiceProvider(new $providerClass);
        }

        //Unset
        unset($services, $di);
    }

    protected function mergeConfig(array $services, array $custom)
    {
        if (!$custom) {
            return $services;
        }

        foreach ($services as $id => $definition) {
            if ( isset($custom[$id]) && !isset($custom[$id]['target']) ) {
                $services[$id]['params'] = $custom[$id];
            } else {
                // $services[$id]
            }
        }
    }

    public function setDi(Container $di)
    {
        $this->di = $di;

        return $this;
    }

    public function getDi()
    {
        if (!$this->di) {
            $this->di = Ioc::build();
        }

        return $this->di;
    }


}// end class Configurator
